
package cn.gwm.flink.streaming.function.reduce;

import cn.gwm.flink.streaming.beans.estimateSoh.ConfigData;
import cn.gwm.flink.streaming.beans.estimateSoh.EstimateSohRecord;
import cn.gwm.flink.streaming.beans.estimateSoh.EstimateSohRecordPhev;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import org.apache.flink.api.common.functions.ReduceFunction;

import java.math.BigDecimal;
import java.util.Objects;

/**
 * @author GW00283474
 */
public class EstimateSohCountReduceEvFunction implements ReduceFunction<EstimateSohRecord> {
    static final Log log = LogFactory.get();
    /**
     * 数据舍弃判断：dVmax 或者dVmin小于等于 ？V
     */
    static String DATA_DISCARD_MAX ="dataDiscardMax";
    /**
     * 数据舍弃判断：dVmax 或者dVmin大于等于 ？V
     */
    static String DATA_DISCARD_MIN = "dataDiscardMin";
    @Override
    public EstimateSohRecord reduce(EstimateSohRecord value1, EstimateSohRecord value2) throws Exception {
        EstimateSohRecord last=value2;
        EstimateSohRecord current = value1;
        //单体最大电压两次的差值(本次减上一次)
        BigDecimal dvMax = current.getBMS_RMC_CellVoltMax().subtract(last.getBMS_RMC_CellVoltMax()).setScale(2, BigDecimal.ROUND_HALF_UP);
        //单体最小电压两次的差值(本次减上一次)
        BigDecimal dvMin = current.getBMS_RMC_CellVoltMin().subtract(last.getBMS_RMC_CellVoltMin()).setScale(2, BigDecimal.ROUND_HALF_UP);
        current.setDvMax(dvMax);
        current.setDvMin(dvMin);

        //动力电池内部SOC最大值两次的差值(本次减上一次)
        BigDecimal differenceSocMax = current.getBMS_InnerSOCmax().subtract(last.getBMS_InnerSOCmax()).setScale(2, BigDecimal.ROUND_HALF_UP);
        //动力电池内部SOC最大值两次的差值(本次减上一次)
        BigDecimal differenceSocMin = current.getBMS_InnerSOCmin().subtract(last.getBMS_InnerSOCmin()).setScale(2, BigDecimal.ROUND_HALF_UP);
        current.setDifferenceSocMax(differenceSocMax);
        current.setDifferenceSocMin(differenceSocMin);

        //计算充放电容量差两次的差值(本次减上一次)
        BigDecimal dQ = current.getDQ().subtract(last.getDQ());
        current.setDQ(dQ);
        if (0 != dvMax.doubleValue()) {
            //计算比值1(等于dQ除以dV_max)
            current.setRatio1(dQ.divide(dvMax, 2, BigDecimal.ROUND_HALF_UP));
        }
        if (0 != dvMin.doubleValue()) {
            //计算比值2(等于dQ除以dV_min)
            current.setRatio2(dQ.divide(dvMin, 2, BigDecimal.ROUND_HALF_UP));
        }
        //检查神经网络模型舍弃条件
        checkAbandon(current);
        //检查容量法舍弃条件（一期需求暂时先给true）
        //checkCapacityAbandon(current);
        current.setCapacityAbandonFlag(true);
        return current;
    }


    /**
     * 检查神经网络模型舍弃条件
     * @param record
     */
    void checkAbandon(EstimateSohRecord record) {
        if (BooleanUtil.or(null == record.getRatio1(), null == record.getRatio2())) {
            record.setNetModelAbandonFlag(true);
        }else{
            //比值1或比值2其一为正的舍弃
            boolean ratio1Flag= NumberUtil.isGreater(record.getRatio1(),new BigDecimal("0"));
            boolean ratio2Flag= NumberUtil.isGreater(record.getRatio2(),new BigDecimal("0"));
            if(BooleanUtil.or(ratio1Flag,ratio2Flag)){
                record.setNetModelAbandonFlag(true);
            }
            //dV_max或dV_min其一值在[-0,01,0.01]内的舍弃
            BigDecimal dataDiscardMax=new BigDecimal("0.01");
            ConfigData configData = record.getConfigDataMap().get(DATA_DISCARD_MAX);
            if(Objects.nonNull(configData)){
                dataDiscardMax=new BigDecimal(configData.getConfigValue());
            }
            BigDecimal dataDiscardMin=new BigDecimal("-0.01");
            ConfigData configDataMin = record.getConfigDataMap().get(DATA_DISCARD_MIN);
            if(Objects.nonNull(configDataMin)){
                dataDiscardMin=new BigDecimal(configDataMin.getConfigValue());
            }
            boolean dvMaxFlag=BooleanUtil.and(NumberUtil.isGreaterOrEqual(record.getDvMax(),dataDiscardMin),
                    NumberUtil.isLessOrEqual(record.getDvMax(),dataDiscardMax));
            boolean dvMinFlag=BooleanUtil.and(NumberUtil.isGreaterOrEqual(record.getDvMin(),dataDiscardMin),
                    NumberUtil.isLessOrEqual(record.getDvMin(),dataDiscardMax));
            if(BooleanUtil.or(dvMaxFlag,dvMinFlag)){
                record.setNetModelAbandonFlag(true);
            }

        }
    }

    /**
     * 检查容量法舍弃条件
     * @param record
     */
    void checkCapacityAbandon(EstimateSohRecord record){
        boolean dqFlag=BooleanUtil.and(NumberUtil.isGreaterOrEqual(record.getDQ(),new BigDecimal("-10")),
                NumberUtil.isLessOrEqual(record.getDQ(),new BigDecimal("10")));
        //-10<=dQ<=10的舍弃
        if(dqFlag){
            record.setCapacityAbandonFlag(true);
        }
        //difference_soc_max或difference_soc_min其一值在[0.00,5.00]内的舍弃
        boolean diffSocMax=BooleanUtil.and(NumberUtil.isGreaterOrEqual(record.getDifferenceSocMax(),new BigDecimal("0.00")),
                NumberUtil.isLessOrEqual(record.getDifferenceSocMax(),new BigDecimal("5.00")));
        boolean diffSocMin=BooleanUtil.and(NumberUtil.isGreaterOrEqual(record.getDifferenceSocMin(),new BigDecimal("0.00")),
                NumberUtil.isLessOrEqual(record.getDifferenceSocMin(),new BigDecimal("5.00")));
        if(BooleanUtil.or(diffSocMax,diffSocMin)){
            record.setCapacityAbandonFlag(true);
        }
    }
}
